﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using QW.Core.Exceptions;
using QW.Domain;
using QW.Domain.Module;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QW.Found.Extensions
{
    /// <summary>
    /// 领域模块构建器
    /// </summary>
    public static class DomainModuleExtensionss
    {
        /// <summary>
        /// 注册选项
        /// </summary>
        public static Dictionary<Type, IDomainModuleOption> registrationOptions = new Dictionary<Type, IDomainModuleOption>();

        /// <summary>
        /// 注册领域模块
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="services"></param>
        /// <param name="optionsBuilder"></param>
        /// <returns></returns>
        public static IServiceCollection AddDomainModule<T>(this IServiceCollection services, Action<IDomainModuleOption> optionsBuilder = null) where T : IDomainModule, new()
        {
            var _type = typeof(T);
            IDomainModuleOption regOption;

            if (registrationOptions.ContainsKey(_type))
            {
                regOption = registrationOptions[_type];
                throw new QWBaseException("模块不可以重复注册");
            }
            else { regOption = new DomainModuleRegistrationOptions(_type, services); }

            optionsBuilder?.Invoke(regOption);

            if (registrationOptions.ContainsKey(_type)) { registrationOptions[_type] = regOption; }
            else { registrationOptions.Add(_type, regOption); }

            var instance = new T();
            //instance.Option = regOption;

            services.AddSingleton(_type, instance);

            //触发OnConfiguration
            DomainModuleConfigurationContext _context = new DomainModuleConfigurationContext(services, regOption);
            instance.OnConfiguration(_context);

            return services;
        }

        /// <summary>
        /// 初始化领域模块
        /// </summary>
        public static void InitializeDomainModule(this IApplicationBuilder app)
        {
            if (registrationOptions != null && registrationOptions.Count > 0)
            {
                foreach (var item in registrationOptions)
                {
                    if (item.Key == null) { continue; }
                    var _obj = (IDomainModule)app.ApplicationServices.GetService(item.Key);
                    if (_obj == null) { continue; }
                    //_obj.Option = item.Value;
                    DomainModuleInitializationContext _context = new DomainModuleInitializationContext(app.ApplicationServices, item.Value);
                    _obj.OnInitialize(_context);

                }
            }
        }
    }
}
